package edu.pdx.cs410J.grader; import com.google.common.io.ByteStreams; import com.icegreen.greenmail.imap.AuthorizationException; import com.icegreen.greenmail.imap.ImapHostManager; import com.icegreen.greenmail.store.FolderException; import com.icegreen.greenmail.store.FolderListener; import com.icegreen.greenmail.store.MailFolder; import com.icegreen.greenmail.user.GreenMailUser; import org.junit.Test; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.*; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; public class SendAndReceiveMultipartWithGreenmailIT extends GreenmailIntegrationTestCase { private final String emailFolderName = ProjectSubmissionsProcessor.EMAIL_FOLDER_NAME; @Override protected void doSomethingWithUser(GreenMailUser user) throws FolderException, AuthorizationException { moveEmailsFromInboxToProjectSubmissions(user); } private void moveEmailsFromInboxToProjectSubmissions(GreenMailUser user) throws AuthorizationException, FolderException { ImapHostManager manager = emailServer.getManagers().getImapHostManager(); MailFolder submissions = manager.createMailbox(user, emailFolderName); MailFolder inbox = manager.getInbox(user); inbox.addListener(new FolderListener() { @Override public void expunged(int msn) { } @Override public void added(int msn) { try { inbox.copyMessage(msn, submissions); } catch (FolderException ex) { throw new IllegalStateException("Can't copy message to submissions folder", ex); } } @Override public void flagsUpdated(int msn, Flags flags, Long uid) { } @Override public void mailboxDeleted() { } }); } @Test public void sendAndFetchMailMessageWithMultipleAttachments() throws IOException, MessagingException, GeneralSecurityException { sendMailWithAttachedZipFile(); fetchAttachmentsFromUnreadMessagesInFolder(); } public void fetchAttachmentsFromUnreadMessagesInFolder() throws GeneralSecurityException, MessagingException { Store store = connectToIMAPServer(); Folder folder = openFolder(store, emailFolderName); fetchAttachmentsFromUnreadMessagesInFolder(folder); try { folder.close(false); store.close(); } catch (MessagingException ex) { throw new IllegalStateException("While closing folder and store", ex); } } private void fetchAttachmentsFromUnreadMessagesInFolder(Folder folder) throws MessagingException { Message[] messages = folder.getMessages(); FetchProfile profile = new FetchProfile(); profile.add(FetchProfile.Item.ENVELOPE); profile.add(FetchProfile.Item.FLAGS); folder.fetch(messages, profile); for (Message message : messages) { System.out.println(message.getContentType()); assertThat(message.getContentType() + " is not multi-part", isMultipartMessage(message), equalTo(true)); } } private boolean isMultipartMessage(Message message) throws MessagingException { return message.isMimeType("multipart/*"); } private void sendMailWithAttachedZipFile() throws IOException, MessagingException { File tempDirectory = new File(System.getProperty("java.io.tmpdir")); File tempFile = File.createTempFile("TempFile", ".java", tempDirectory); tempFile.createNewFile(); File[] filesToSubmit = new File[]{tempFile}; File zipFile = File.createTempFile("TempFile", ".zip", tempDirectory); mailTA(makeZipFile(zipFile, filesToSubmit)); } public File makeZipFile(File zipFile, File[] files) throws IOException { ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile)); zos.setMethod(ZipOutputStream.DEFLATED); // Add the source files to the Zip for (File file : files) { String fileName = file.getName(); System.out.println("Adding " + fileName + " to zip"); ZipEntry entry = new ZipEntry(fileName); entry.setTime(file.lastModified()); entry.setSize(file.length()); entry.setMethod(ZipEntry.DEFLATED); // Add the entry to the ZIP file zos.putNextEntry(entry); ByteStreams.copy(new FileInputStream(file), zos); zos.closeEntry(); } zos.close(); return zipFile; } private void mailTA(File zipFile) throws MessagingException { MimeMessage message = newEmailTo(newEmailSession(true), emailAddress, "Email subject"); MimeBodyPart textPart = createTextPartOfTAEmail(); MimeBodyPart filePart = createZipAttachment(zipFile); Multipart mp = new MimeMultipart(); mp.addBodyPart(textPart); mp.addBodyPart(filePart); message.setContent(mp); Transport.send(message); } private MimeBodyPart createTextPartOfTAEmail() throws MessagingException { MimeBodyPart textPart = new MimeBodyPart(); textPart.setContent("This is some text to be displayed inline", "text/plain"); // Try not to display text as separate attachment textPart.setDisposition("inline"); return textPart; } private MimeBodyPart createZipAttachment(File zipFile) throws MessagingException { // Now attach the Zip file DataSource ds = new FileDataSource(zipFile) { @Override public String getContentType() { return "application/zip"; } }; DataHandler dh = new DataHandler(ds); MimeBodyPart filePart = new MimeBodyPart(); String zipFileTitle = "ZipFile.zip"; filePart.setDataHandler(dh); filePart.setFileName(zipFileTitle); filePart.setDescription("Zip File"); return filePart; } }